//
//  SpriteView.m
//  PhotoMagician
//
//  Created by yang weiwei on 12-7-9.
//  Copyright 2012 __MyCompanyName__. All rights reserved.
//

#import "SpriteView.h"
#import "CImageUtil.h"
//#import "CPixelContext.h"


#define SPRITE_SIZE	100

#define H_MARGIN	10
#define V_MARGIN	10

CGRect rectScale(CGRect rc, float xs, float ys)
{
	rc.size = CGSizeMake(rc.size.width*xs, rc.size.height*ys);
	
	return rc;
}	


@implementation SpriteView


- (id) initWithFrame:(CGRect)frame
{
	self = [super initWithFrame:frame];
	if (self != nil) {
		imageView = [[UIImageView alloc] init];
		[self addSubview:imageView];
		
		cancelImageView = [[UIImageView alloc] initWithImage:[CImageUtil imageFromFile:@"cancelImg.png"]];
		[self addSubview:cancelImageView];
		cancelImageView.frame = rectScale(cancelImageView.frame, 0.25, 0.25);
		
		rotateImageView = [[UIImageView alloc] initWithImage:[CImageUtil  imageFromFile:@"roatImg.png"]];
		[self addSubview:rotateImageView];
		rotateImageView.frame = rectScale(rotateImageView.frame, 0.25, 0.25);
		
		self.userInteractionEnabled = TRUE;
		self.backgroundColor = [UIColor clearColor];
		
		self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | 
								UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |
								UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
		
		imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | 
									UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |
									UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
		
		isEditting = FALSE;
	}
	return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        NSData* imageData = nil;
        
        imageView = [aDecoder decodeObjectForKey:STRINGIFY(imageView)];
        imageData = [aDecoder decodeObjectForKey:STRINGIFY(imageView.image)];
        if (imageData) {
            imageView.image = [UIImage imageWithData:imageData];
        }
        
        touchOffset = [aDecoder decodeCGPointForKey:STRINGIFY(touchOffset)];
        
        rotateImageView = [aDecoder decodeObjectForKey:STRINGIFY(rotateImageView)];
        imageData = [aDecoder decodeObjectForKey:STRINGIFY(rotateImageView.image)];
        if (imageData) {
            rotateImageView.image = [UIImage imageWithData:imageData];
        }
        
        cancelImageView = [aDecoder decodeObjectForKey:STRINGIFY(cancelImageView)];
        imageData = [aDecoder decodeObjectForKey:STRINGIFY(cancelImageView.image)];
        if (imageData) {
            cancelImageView.image = [UIImage imageWithData:imageData];
        }
        
        isTransforming = [aDecoder decodeBoolForKey:STRINGIFY(isTransforming)];
        isEditting = [aDecoder decodeBoolForKey:STRINGIFY(isEditting)];
        startTransform = [aDecoder decodeCGAffineTransformForKey:STRINGIFY(startTransform)];
        _userObject = [aDecoder decodeObjectForKey:STRINGIFY(_userObject)];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [super encodeWithCoder:aCoder];
    [aCoder encodeObject:imageView forKey:STRINGIFY(imageView)];
    if (imageView.image) {
        [aCoder encodeObject:UIImagePNGRepresentation(imageView.image) forKey:STRINGIFY(imageView.image)];
    }
    
    [aCoder encodeCGPoint:touchOffset forKey:STRINGIFY(touchOffset)];
    [aCoder encodeObject:rotateImageView forKey:STRINGIFY(rotateImageView)];
    if (rotateImageView.image) {
        [aCoder encodeObject:UIImagePNGRepresentation(rotateImageView.image) forKey:STRINGIFY(rotateImageView.image)];
    }
    
    [aCoder encodeObject:cancelImageView forKey:STRINGIFY(cancelImageView)];
    if (cancelImageView.image) {
        [aCoder encodeObject:UIImagePNGRepresentation(cancelImageView.image) forKey:STRINGIFY(cancelImageView.image)];
    }
    
    [aCoder encodeBool:isTransforming forKey:STRINGIFY(isTransforming)];
    [aCoder encodeBool:isEditting forKey:STRINGIFY(isEditting)];
    [aCoder encodeCGAffineTransform:startTransform forKey:STRINGIFY(startTransform)];
    [aCoder encodeObject:_userObject forKey:STRINGIFY(_userObject)];
}

- (void) dealloc
{
	
}

- (void)drawRect:(CGRect)rect {
	if (!self.isEditting) {
		return;
	}
	
	int lineWidth = 2;
	
	CGRect rc;
	rc = CGRectMake(cancelImageView.center.x-lineWidth/2, 
					cancelImageView.center.y-lineWidth/2, 
					rotateImageView.center.x-cancelImageView.center.x+lineWidth,
					rotateImageView.center.y-cancelImageView.center.y+lineWidth);
	
	CGContextRef ctx;
	ctx = UIGraphicsGetCurrentContext();
	UIColor *color;
	color = [UIColor blueColor];
	CGContextSetStrokeColorWithColor(ctx, [color CGColor]);
	CGContextSetLineWidth(ctx, lineWidth);
	CGContextStrokeRect(ctx, rc);
}

- (UIImage*)image {
	return imageView.image;
}

- (void)setImage:(UIImage*)image {
	imageView.image = image;
	
	float maxRadius;
	maxRadius = rotateImageView.frame.size.width > cancelImageView.frame.size.width?
	rotateImageView.frame.size.width/2:cancelImageView.frame.size.width/2;
	
	CGRect frame;
	CGPoint center;
	
	float xRatio = SPRITE_SIZE/image.size.width;
	float yRatio = SPRITE_SIZE/image.size.height;
	float fRatio = xRatio>yRatio?yRatio:xRatio;
	
	center = self.center;
	frame = self.frame;
	frame.size = CGSizeMake(image.size.width*fRatio+2*H_MARGIN+2*maxRadius, 
							image.size.height*fRatio+2*V_MARGIN+2*maxRadius);
	self.frame = frame;
	self.center = center;
	
	frame = imageView.frame;
	frame.size = CGSizeMake(image.size.width*fRatio, image.size.height*fRatio);
	imageView.frame = frame;
	imageView.center = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
	
	rotateImageView.center = CGPointMake(self.frame.size.width-maxRadius,
										 self.frame.size.height-maxRadius);
	cancelImageView.center = CGPointMake(maxRadius, maxRadius);
}

- (void)setView:(UIView*)aView {
	UIImage* img = [CImageUtil imageFromView:aView];
	
	[self setImage:img];
	[self addSubview:aView];
	aView.frame = imageView.frame;
	aView.transform = imageView.transform;
	[imageView removeFromSuperview];
	imageView = nil;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	UITouch* touch = [touches anyObject];
	CGPoint point = [touch locationInView:self.superview];
	
	if (isEditting) {
		touchOffset = CGPointMake(self.center.x-point.x, self.center.y-point.y);
		
		CGPoint pointInSelf = [touch locationInView:self];
		if (CircleContainsPoint(rotateImageView.frame, pointInSelf)) {
			isTransforming = TRUE;
			startTransform = self.transform;
		} else if (CircleContainsPoint(cancelImageView.frame, pointInSelf)) {
			UIView* spview = self.superview;
			[self removeFromSuperview];
			[self informContainerViewDeleted:spview];
		}
	} else {
		
	}
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	UITouch* touch = [touches anyObject];
	CGPoint point = [touch locationInView:self.superview];
	
	if (isEditting) {
		if (!isTransforming) {
			self.center = CGPointMake(point.x+touchOffset.x, point.y+touchOffset.y);		
		} else {
			CGPoint curOffset;
			curOffset = CGPointMake(self.center.x-point.x, self.center.y-point.y);
			
			float preLen = sqrtf(touchOffset.x*touchOffset.x + touchOffset.y*touchOffset.y);
			float curLen = sqrtf(curOffset.x*curOffset.x + curOffset.y*curOffset.y);
			float ratioLen = curLen/preLen;
			
			float preAngle = atan2f(touchOffset.y, touchOffset.x);
			float curAngle = atan2f(curOffset.y, curOffset.x);
			float deltaAngle = curAngle-preAngle;
			
			CGAffineTransform at;
			at = CGAffineTransformRotate(startTransform, deltaAngle);
			at = CGAffineTransformScale(at, ratioLen, ratioLen);
			
			self.transform = at;
			
			CGAffineTransform it;
			it = CGAffineTransformInvert(self.transform);
			rotateImageView.transform = it;
			cancelImageView.transform = it;
		}		
	} else {
		
	}
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	UITouch* touch = [touches anyObject];
	CGPoint point = [touch locationInView:self.superview];
	
	isTransforming = FALSE;
	
	if (isEditting) {
		
	} else {
		if (CGRectContainsPoint(self.frame, point)) {
			if ([self.superview isKindOfClass:[SpriteContainerView class]]) {
				[(SpriteContainerView*)self.superview unselectAllSprite];
			}
			
			self.isEditting = TRUE;
			[self.superview bringSubviewToFront:self];
		}
	}
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
	
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
	if (isEditting) {
		return CGRectContainsPoint(self.bounds, point);
	} else {
		return CGRectContainsPoint(CGRectInset(self.bounds, self.bounds.size.width/4, self.bounds.size.height/4), point);
	}
}

- (bool)isEditting {
	return isEditting;
}

- (void)setIsEditting:(bool)editting {	
	if (isEditting == editting) {
		return;
	}
	
	isEditting = editting;
	
	if (isEditting) {
		cancelImageView.hidden = FALSE;
		rotateImageView.hidden = FALSE;
		[self informContainerViewEditStateChanged];
	} else {
		cancelImageView.hidden = TRUE;
		rotateImageView.hidden = TRUE;
		[self informContainerViewEditStateChanged];
	}
	
	[self setNeedsDisplay];
}

- (UIView *)getViewWithClass:(Class)cls
{
	for (UIView* view in self.subviews) {
		if ([view isKindOfClass:cls]) {
			return view;
		}
	}
	return nil;
}

- (void)informContainerViewEditStateChanged
{
	if (self.superview && [self.superview isKindOfClass:[SpriteContainerView class]]) {
		SpriteContainerView* containerView = (SpriteContainerView*)self.superview;
		[containerView spriteEditStateChanged:self];
	}
}

- (void)informContainerViewDeleted:(UIView*)spview
{
	if (spview && [spview isKindOfClass:[SpriteContainerView class]]) {
		SpriteContainerView* containerView = (SpriteContainerView*)spview;
		if (containerView.spriteDelete) {
			containerView.spriteDelete(containerView, self);
		}
	}
}

//- (BOOL)pixelIsClear:(CGPoint)point inView:(UIView*)view
//{
//	BOOL isClear = true;
//
//	UIImage* image = [CImageUtil imageFromView:view];
//	CPixelContext* pixels = [[CPixelContext alloc] initWithImage:image];
//	int A = PIXEL_RGBA(pixels, point.x, point.y);
//	if (A > 0) {
//		isClear = false;
//	}
//	
//	return isClear;
//}

@end


@implementation SpriteContainerView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	for (UIView* subview in self.subviews) {
		if ([subview isKindOfClass:[SpriteView class]]) {
			SpriteView* spv = (SpriteView*)subview;
			
			if (spv.isEditting) {
				bool canUnselect = true;
				if (self.shouldUnselectSprite) {
					canUnselect = self.shouldUnselectSprite(self, spv);
				}
				
				if (canUnselect) {
					spv.isEditting = FALSE;
				}
			}
		}
	}
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//	SpriteView* curSpriteView = NULL;
//	
//	if ([self.subviews count]) {
//		UIView* topChildView;
//		topChildView = [self.subviews lastObject];
//		
//		if ([topChildView isKindOfClass:[SpriteView class]]) {
//			curSpriteView = (SpriteView*)topChildView;
//		}
//	}
//	
//	if (curSpriteView && curSpriteView.isEditting) {
//		curSpriteView.isEditting = FALSE;
//	}
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
	
}

- (void)unselectAllSprite {
	for (UIView *view in self.subviews) {
		if ([view isKindOfClass:[SpriteView class]]) {
			((SpriteView*)view).isEditting = FALSE;
		}
	}
}

- (void)addSprite:(SpriteView*)view {
	[self unselectAllSprite];
	[self addSubview:view];
	view.isEditting = TRUE;
}

- (void)selectTopSprite:(bool)select {
	SpriteView* spriteView = NULL;
	
	if ([self.subviews count]) {
		UIView* topView = [self.subviews lastObject];
		if ([topView isKindOfClass:[SpriteView class]]) {
			spriteView = (SpriteView*)topView;
			spriteView.isEditting = select;
		}
	}
}

- (SpriteView *)getTopSprite
{
	SpriteView* spriteView = NULL;
	
	if ([self.subviews count]) {
		UIView* topView = [self.subviews lastObject];
		if ([topView isKindOfClass:[SpriteView class]]) {
			spriteView = (SpriteView*)topView;
		}
	}
	
	return spriteView;
}

- (void)spriteEditStateChanged:(SpriteView*)sprite
{
	if (sprite) {
		if (sprite.isEditting) {
			if (self.spriteSelected) {
				self.spriteSelected(self, sprite);
			}
		} else {
			if (self.spriteUnselected) {
				self.spriteUnselected(self, sprite);
			}
		}
	}
}

@end
